const { BarkChannel } = require('./channels/bark');
const { EmailChannel } = require('./channels/email');

class NotificationService {
  constructor(options = {}) {
    this.channels = {
      bark: options.bark instanceof BarkChannel ? options.bark : new BarkChannel(options.bark),
      email: options.email instanceof EmailChannel ? options.email : new EmailChannel(options.email)
    };
  }

  /**
   * Send message via one or multiple channels
   * @param {Object} message common fields: { title, body }
   * @param {Object} options { channels: string[] | 'all', perChannel: { bark: {...}, email: {...} } }
   */
  async send(message, options = {}) {
    const targetChannels = this._resolveChannels(options.channels);
    const tasks = targetChannels.map((ch) => {
      const channel = this.channels[ch];
      const perMsg = Object.assign({}, message, options.perChannel && options.perChannel[ch] ? options.perChannel[ch] : {});
      return channel.send(perMsg).then(
        (res) => ({ channel: ch, ok: true, result: res }),
        (err) => ({ channel: ch, ok: false, error: err.message, detail: err.results || undefined })
      );
    });
    const results = await Promise.all(tasks);
    const ok = results.every(r => r.ok);
    if (!ok) {
      const error = new Error('One or more channel sends failed');
      error.results = results;
      throw error;
    }
    return results;
  }

  _resolveChannels(chs) {
    if (!chs || chs === 'all') return Object.keys(this.channels);
    if (Array.isArray(chs)) return chs.filter(c => this.channels[c]);
    if (typeof chs === 'string' && this.channels[chs]) return [chs];
    throw new Error('Invalid channels option');
  }
}

module.exports = { NotificationService };


